using System;
using System.Reflection;

namespace Kopernikus.Parsing.GenericActions
{
    internal class ReflectedSemanticAction<TParser, S> : ISemanticAction<TParser, S>
    {
        private readonly ISemanticActionParametersFixup m_fixup;
        private readonly MethodInfo m_method;

        public ReflectedSemanticAction(MethodInfo method) : this(method, new SemanticActionParametersFixup(null))
        {
        }

        public ReflectedSemanticAction(MethodInfo method, ISemanticActionParametersFixup fixup)
        {
            m_method = method;
            m_fixup = fixup;
        }

        #region ISemanticAction<TParser,S> Members

        public S Invoke(TParser instance, S[] arguments)
        {
            return (S) m_method.Invoke(instance, m_fixup.Fixup(MakeArgumentArray(arguments)));
        }

        #endregion

        protected virtual object[] MakeArgumentArray(S[] args)
        {
            return Array.ConvertAll<S, object>(args, delegate(S arg) { return arg; });
        }
    }
}